import pygame
import random
import math

# 引入菜单界面
from 菜单.init_menu import draw_menu, handle_menu_click, draw_rules_screen, draw_exit_confirm_dialog, draw_game_menu, draw_main_menu_exit_confirm, draw_game_menu_exit_confirm

# 游戏窗口大小
BLOCK_SIZE = 30
SIDEBAR_WIDTH = 8
WIDTH, HEIGHT = (10 + SIDEBAR_WIDTH) * BLOCK_SIZE, 22 * BLOCK_SIZE
COLUMNS = 10
ROWS = 22

# 颜色定义
BLACK = (0, 0, 0)
DARK_GRAY = (40, 40, 40)
GRAY = (128, 128, 128)
LIGHT_GRAY = (200, 200, 200)
WHITE = (255, 255, 255)
SIDEBAR_BG = (25, 25, 45)
MAIN_BG = (15, 15, 30)
ACCENT = (255, 215, 0)
NEON_BLUE = (0, 255, 255)
DANGER_RED = (255, 80, 80)

# 方块颜色（带渐变效果）
COLORS = [
    (0, 255, 255),  # I - 青色
    (0, 100, 255),  # J - 蓝色
    (255, 165, 0),  # L - 橙色
    (255, 255, 0),  # O - 黄色
    (0, 255, 100),  # S - 绿色
    (160, 32, 240),  # T - 紫色
    (255, 50, 50),  # Z - 红色
]

# 方块阴影颜色
SHADOW_COLORS = [
    (0, 180, 180),
    (0, 70, 180),
    (180, 115, 0),
    (180, 180, 0),
    (0, 180, 70),
    (110, 22, 170),
    (180, 35, 35),
]

# 俄罗斯方块形状
SHAPES = [
    [[1, 1, 1, 1]],  # I
    [[1, 0, 0], [1, 1, 1]],  # J
    [[0, 0, 1], [1, 1, 1]],  # L
    [[1, 1], [1, 1]],  # O
    [[0, 1, 1], [1, 1, 0]],  # S
    [[0, 1, 0], [1, 1, 1]],  # T
    [[1, 1, 0], [0, 1, 1]],  # Z
]

# 等级配置
LEVEL_SPEEDS = [800, 700, 600, 500, 400, 350, 300, 250, 200, 150, 100]
LINES_PER_LEVEL = 10


class ParticleEffect:
    def __init__(self, x, y, color):
        self.x = x
        self.y = y
        self.vx = random.uniform(-3, 3)
        self.vy = random.uniform(-5, -1)
        self.color = color
        self.life = 30
        self.max_life = 30

    def update(self):
        self.x += self.vx
        self.y += self.vy
        self.vy += 0.2  # 重力
        self.life -= 1

    def draw(self, screen):
        if self.life > 0:
            alpha = int(255 * (self.life / self.max_life))
            size = max(1, int(4 * (self.life / self.max_life)))
            color = (*self.color, alpha)
            # 创建带透明度的surface
            particle_surf = pygame.Surface((size * 2, size * 2), pygame.SRCALPHA)
            pygame.draw.circle(particle_surf, color, (size, size), size)
            screen.blit(particle_surf, (self.x - size, self.y - size))


def rotate(shape):
    return [list(row) for row in zip(*shape[::-1])]


def check_collision(board, shape, offset):
    off_x, off_y = offset
    for y, row in enumerate(shape):
        for x, cell in enumerate(row):
            if cell:
                if x + off_x < 0 or x + off_x >= COLUMNS or y + off_y >= ROWS:
                    return True
                if y + off_y >= 0 and board[y + off_y][x + off_x]:
                    return True
    return False


def get_drop_position(board, shape, offset):
    """获取方块的投影位置"""
    drop_y = offset[1]
    while not check_collision(board, shape, [offset[0], drop_y + 1]):
        drop_y += 1
    return drop_y


def remove_full_lines(board):
    full_rows = []
    new_board = []
    for i, row in enumerate(board):
        if all(cell != 0 for cell in row):
            full_rows.append(i)
        else:
            new_board.append(row)

    lines_cleared = len(full_rows)
    for _ in range(lines_cleared):
        new_board.insert(0, [0 for _ in range(COLUMNS)])

    return new_board, lines_cleared, full_rows


def get_font(size, bold=False):
    try:
        return pygame.font.SysFont('SimHei', size, bold=bold)
    except:
        return pygame.font.Font(None, size)


def draw_gradient_rect(surface, color1, color2, rect, vertical=True):
    """绘制渐变矩形"""
    if vertical:
        for y in range(rect.height):
            blend = y / rect.height
            r = int(color1[0] * (1 - blend) + color2[0] * blend)
            g = int(color1[1] * (1 - blend) + color2[1] * blend)
            b = int(color1[2] * (1 - blend) + color2[2] * blend)
            pygame.draw.line(surface, (r, g, b),
                             (rect.x, rect.y + y), (rect.x + rect.width, rect.y + y))
    else:
        for x in range(rect.width):
            blend = x / rect.width
            r = int(color1[0] * (1 - blend) + color2[0] * blend)
            g = int(color1[1] * (1 - blend) + color2[1] * blend)
            b = int(color1[2] * (1 - blend) + color2[2] * blend)
            pygame.draw.line(surface, (r, g, b),
                             (rect.x + x, rect.y), (rect.x + x, rect.y + rect.height))


def draw_rounded_rect(surface, color, rect, radius=12, width=0):
    pygame.draw.rect(surface, color, rect, width=width, border_radius=radius)


def draw_glowing_rect(surface, color, rect, glow_size=2):
    """绘制发光效果的矩形"""
    # 绘制外层发光
    for i in range(glow_size, 0, -1):
        glow_color = tuple(min(255, c + 20 * i) for c in color)
        glow_rect = pygame.Rect(rect.x - i, rect.y - i, rect.width + 2 * i, rect.height + 2 * i)
        pygame.draw.rect(surface, glow_color, glow_rect, border_radius=8)

    # 绘制主体
    pygame.draw.rect(surface, color, rect, border_radius=6)


def draw_block(surface, color, x, y, size, glow=False, shadow=False):
    """绘制单个方块，带3D效果"""
    if shadow:
        # 绘制阴影
        shadow_color = tuple(c // 3 for c in color)
        shadow_rect = pygame.Rect(x + 2, y + 2, size, size)
        pygame.draw.rect(surface, shadow_color, shadow_rect, border_radius=4)

    # 主体方块
    main_rect = pygame.Rect(x, y, size, size)
    if glow:
        draw_glowing_rect(surface, color, main_rect)
    else:
        # 绘制渐变效果
        light_color = tuple(min(255, c + 30) for c in color)
        dark_color = tuple(max(0, c - 30) for c in color)
        draw_gradient_rect(surface, light_color, dark_color, main_rect)

    # 高光效果
    highlight_rect = pygame.Rect(x + 2, y + 2, size - 4, size // 3)
    highlight_color = tuple(min(255, c + 50) for c in color)
    pygame.draw.rect(surface, highlight_color, highlight_rect, border_radius=2)

    # 边框
    pygame.draw.rect(surface, LIGHT_GRAY, main_rect, 1, border_radius=4)


def draw_board(screen, board, current, offset, color, next_shape, next_color,
               score, level, lines, flash_rows=None, paused=False, game_over=False,
               particles=None, show_ghost=True):
    # 背景渐变
    draw_gradient_rect(screen, MAIN_BG, BLACK,
                       pygame.Rect(0, 0, COLUMNS * BLOCK_SIZE, HEIGHT))

    # 绘制网格
    for x in range(COLUMNS + 1):
        pygame.draw.line(screen, DARK_GRAY,
                         (x * BLOCK_SIZE, 0), (x * BLOCK_SIZE, HEIGHT), 1)
    for y in range(ROWS + 1):
        pygame.draw.line(screen, DARK_GRAY,
                         (0, y * BLOCK_SIZE), (COLUMNS * BLOCK_SIZE, y * BLOCK_SIZE), 1)

    # 绘制幽灵方块（投影）
    if show_ghost and current and not game_over:
        ghost_y = get_drop_position(board, current, offset)
        if ghost_y > offset[1]:
            ghost_color = tuple(c // 3 for c in color)
            for y, row in enumerate(current):
                for x, cell in enumerate(row):
                    if cell:
                        px = (x + offset[0]) * BLOCK_SIZE
                        py = (y + ghost_y) * BLOCK_SIZE
                        pygame.draw.rect(screen, ghost_color,
                                         (px + 2, py + 2, BLOCK_SIZE - 4, BLOCK_SIZE - 4))
                        pygame.draw.rect(screen, ghost_color,
                                         (px, py, BLOCK_SIZE, BLOCK_SIZE), 2)

    # 绘制已落下的方块
    for y, row in enumerate(board):
        for x, cell in enumerate(row):
            if cell:
                px, py = x * BLOCK_SIZE, y * BLOCK_SIZE
                block_color = COLORS[cell - 1]

                # 闪烁效果
                if flash_rows and y in flash_rows:
                    flash_intensity = abs(math.sin(pygame.time.get_ticks() * 0.02))
                    block_color = tuple(int(c * flash_intensity + 255 * (1 - flash_intensity))
                                        for c in block_color)

                draw_block(screen, block_color, px, py, BLOCK_SIZE,
                           glow=(flash_rows and y in flash_rows))

    # 绘制当前下落的方块
    if current:
        for y, row in enumerate(current):
            for x, cell in enumerate(row):
                if cell:
                    px = (x + offset[0]) * BLOCK_SIZE
                    py = (y + offset[1]) * BLOCK_SIZE
                    draw_block(screen, color, px, py, BLOCK_SIZE, glow=True)

    # 绘制粒子效果
    if particles:
        for particle in particles:
            particle.draw(screen)

    # 绘制分界线
    divider_x = COLUMNS * BLOCK_SIZE
    pygame.draw.line(screen, NEON_BLUE, (divider_x, 0), (divider_x, HEIGHT), 3)

    # 绘制侧边栏
    sidebar_rect = pygame.Rect(divider_x + 1, 0, WIDTH - divider_x - 1, HEIGHT)
    draw_gradient_rect(screen, SIDEBAR_BG, BLACK, sidebar_rect)

    # 侧边栏内容
    sidebar_x = divider_x + 20
    font_large = get_font(28, bold=True)
    font_medium = get_font(22, bold=True)
    font_small = get_font(18)

    y_pos = 20

    # 分数区域
    score_rect = pygame.Rect(sidebar_x - 10, y_pos, BLOCK_SIZE * 6, 80)
    draw_rounded_rect(screen, (50, 50, 100), score_rect, radius=15)

    score_text = font_medium.render('分数', True, ACCENT)
    score_num = font_large.render(f'{score:,}', True, WHITE)
    screen.blit(score_text, (score_rect.x + 15, score_rect.y + 10))
    screen.blit(score_num, (score_rect.x + 15, score_rect.y + 40))

    y_pos += 100

    # 等级和行数
    level_rect = pygame.Rect(sidebar_x - 10, y_pos, BLOCK_SIZE * 6, 80)
    draw_rounded_rect(screen, (80, 50, 50), level_rect, radius=15)

    level_text = font_small.render(f'等级: {level}', True, ACCENT)
    lines_text = font_small.render(f'行数: {lines}', True, WHITE)
    screen.blit(level_text, (level_rect.x + 15, level_rect.y + 15))
    screen.blit(lines_text, (level_rect.x + 15, level_rect.y + 45))

    y_pos += 100

    # 下一个方块区域
    next_rect = pygame.Rect(sidebar_x - 10, y_pos, BLOCK_SIZE * 6, 120)
    draw_rounded_rect(screen, (60, 80, 60), next_rect, radius=15)

    next_text = font_medium.render('下一个', True, ACCENT)
    screen.blit(next_text, (next_rect.x + 15, next_rect.y + 10))

    # 绘制下一个方块
    if next_shape:
        shape_w = len(next_shape[0]) * BLOCK_SIZE
        shape_h = len(next_shape) * BLOCK_SIZE
        start_x = next_rect.x + (next_rect.width - shape_w) // 2
        start_y = next_rect.y + 45 + (60 - shape_h) // 2

        for y, row in enumerate(next_shape):
            for x, cell in enumerate(row):
                if cell:
                    px = start_x + x * BLOCK_SIZE
                    py = start_y + y * BLOCK_SIZE
                    draw_block(screen, next_color, px, py, BLOCK_SIZE, glow=True)

    y_pos += 140

    # 操作说明
    controls_rect = pygame.Rect(sidebar_x - 10, y_pos, BLOCK_SIZE * 6, 200)
    draw_rounded_rect(screen, (40, 60, 80), controls_rect, radius=15)

    controls_title = font_medium.render('操作', True, ACCENT)
    screen.blit(controls_title, (controls_rect.x + 15, controls_rect.y + 10))

    controls = [
        ('← →', '移动'),
        ('↓', '软降'),
        ('↑', '旋转'),
        ('空格', '硬降'),
        ('P', '暂停'),
    ]

    for i, (key, desc) in enumerate(controls):
        key_text = font_small.render(key, True, WHITE)
        desc_text = font_small.render(desc, True, LIGHT_GRAY)
        y_offset = controls_rect.y + 45 + i * 28
        screen.blit(key_text, (controls_rect.x + 15, y_offset))
        screen.blit(desc_text, (controls_rect.x + 85, y_offset))

    # 游戏状态覆盖
    if paused and not game_over:
        # 暂停遮罩
        pause_overlay = pygame.Surface((COLUMNS * BLOCK_SIZE, HEIGHT))
        pause_overlay.set_alpha(128)
        pause_overlay.fill(BLACK)
        screen.blit(pause_overlay, (0, 0))

        pause_font = get_font(48, bold=True)
        pause_text = pause_font.render('暂停', True, ACCENT)
        pause_rect = pause_text.get_rect(center=(COLUMNS * BLOCK_SIZE // 2, HEIGHT // 2))

        # 绘制发光效果
        for i in range(5):
            glow_color = tuple(min(255, c + 30 - i * 5) for c in ACCENT)
            glow_text = pause_font.render('暂停', True, glow_color)
            screen.blit(glow_text, (pause_rect.x - i, pause_rect.y - i))

        screen.blit(pause_text, pause_rect)

    if game_over:
        # 游戏结束遮罩
        game_over_overlay = pygame.Surface((COLUMNS * BLOCK_SIZE, HEIGHT))
        game_over_overlay.set_alpha(180)
        game_over_overlay.fill(DANGER_RED)
        screen.blit(game_over_overlay, (0, 0))

        over_font = get_font(36, bold=True)
        restart_font = get_font(24)

        over_text = over_font.render('游戏结束', True, WHITE)
        restart_text = restart_font.render('按R重新开始', True, LIGHT_GRAY)

        over_rect = over_text.get_rect(center=(COLUMNS * BLOCK_SIZE // 2, HEIGHT // 2 - 40))
        restart_rect = restart_text.get_rect(center=(COLUMNS * BLOCK_SIZE // 2, HEIGHT // 2 + 20))

        screen.blit(over_text, over_rect)
        screen.blit(restart_text, restart_rect)

    # 移除pygame.display.flip()调用，避免在MOUSEMOTION事件中重复刷新屏幕
    # pygame.display.flip()


# 原来的handle_events函数已被删除，事件处理已集成到主循环中


def calculate_score(lines_cleared, level):
    """计算分数"""
    base_scores = [0, 100, 300, 500, 800]  # 0, 1, 2, 3, 4行
    return base_scores[min(lines_cleared, 4)] * (level + 1)


def reset_game():
    """重置游戏状态"""
    return {
        'board': [[0 for _ in range(COLUMNS)] for _ in range(ROWS)],
        'current_shape': random.choice(SHAPES),
        'current_color': random.choice(COLORS),
        'next_shape': random.choice(SHAPES),
        'next_color': random.choice(COLORS),
        'offset': [COLUMNS // 2 - 2, 0],
        'score': 0,
        'level': 1,
        'lines': 0,
        'paused': False,
        'game_over': False,
        'flash_rows': None,
        'flash_timer': 0,
        'particles': [],
        'fall_time': 0,
        'soft_drop_time': 0,
    }


def spawn_particles(x, y, color, count=8):
    """生成粒子效果"""
    particles = []
    for _ in range(count):
        particles.append(ParticleEffect(x, y, color))
    return particles


def main():
    pygame.init()
    screen = pygame.display.set_mode((WIDTH, HEIGHT))
    pygame.display.set_caption('俄罗斯方块 - 增强版')
    clock = pygame.time.Clock()

    # 游戏状态
    game_state = reset_game()
    
    # 菜单状态
    menu_state = 'main'  # 'main', 'rules', 'game', 'game_menu', 'exit_confirm'
    menu_buttons = []
    showing_rules = False
    showing_exit_confirm = False
    exit_confirm_from_main = False  # 区分退出确认来自主菜单还是游戏内菜单
    showing_game_menu = False  # 游戏内菜单状态
    scroll_offset = 0
    content_height = 0
    content_area_height = 0
    dragging_scrollbar = False  # 滚动条拖拽状态

    # 游戏循环
    running = True
    while running:
        dt = clock.tick(60)  # 60 FPS

        # 获取按键状态（用于软降）
        keys_pressed = pygame.key.get_pressed()

        # 菜单事件处理
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.MOUSEBUTTONDOWN:
                # 只处理鼠标左键点击
                if event.button == 1:  # 左键
                    if menu_state == 'exit_confirm':
                        # 退出确认界面点击处理
                        if exit_confirm_from_main:
                            # 来自主菜单的退出确认
                            yes_button, no_button = draw_main_menu_exit_confirm(screen, WIDTH, HEIGHT)
                            if yes_button.collidepoint(event.pos):
                                # 直接关闭游戏
                                running = False
                            elif no_button.collidepoint(event.pos):
                                # 返回主菜单
                                menu_state = 'main'
                                showing_exit_confirm = False
                                exit_confirm_from_main = False
                        else:
                            # 来自游戏内菜单的退出确认
                            yes_button, no_button = draw_game_menu_exit_confirm(screen, WIDTH, HEIGHT)
                            if yes_button.collidepoint(event.pos):
                                # 直接退出游戏
                                running = False
                            elif no_button.collidepoint(event.pos):
                                # 关闭退出确认对话框，重新打开游戏内菜单
                                menu_state = 'game_menu'
                                showing_exit_confirm = False
                                showing_game_menu = True
                                exit_confirm_from_main = False
                    elif menu_state == 'main':
                        # 主菜单点击处理
                        result = handle_menu_click(event.pos, menu_buttons)
                        if result == "start":
                            menu_state = 'game'
                            game_state = reset_game()
                        elif result == "rules":
                            menu_state = 'rules'
                            showing_rules = True
                            showing_game_menu = False  # 确保来自主菜单
                            # 初始化内容高度变量
                            content_area_height = HEIGHT - 160
                            # 临时调用一次绘制函数来获取内容高度
                            _, content_height, _ = draw_rules_screen(screen, WIDTH, HEIGHT, scroll_offset)
                        elif result == "exit":
                            menu_state = 'exit_confirm'
                            showing_exit_confirm = True
                            exit_confirm_from_main = True # 标记来自主菜单
                    elif menu_state == 'game_menu':
                        # 游戏内菜单点击处理
                        continue_button, rules_button, exit_button = draw_game_menu(screen, WIDTH, HEIGHT)
                        if continue_button.collidepoint(event.pos):
                            # 继续游戏
                            menu_state = 'game'
                            showing_game_menu = False
                        elif rules_button.collidepoint(event.pos):
                            # 打开游戏说明
                            menu_state = 'rules'
                            showing_rules = True
                            showing_game_menu = True  # 明确设置为True，表示来自游戏内菜单
                            # 初始化内容高度变量
                            content_area_height = HEIGHT - 160
                            # 临时调用一次绘制函数来获取内容高度
                            _, content_height, _ = draw_rules_screen(screen, WIDTH, HEIGHT, scroll_offset)
                        elif exit_button.collidepoint(event.pos):
                            # 退出游戏确认 - 关闭游戏内菜单，显示退出确认对话框
                            menu_state = 'exit_confirm'
                            showing_exit_confirm = True
                            showing_game_menu = False  # 关闭游戏内菜单
                            exit_confirm_from_main = False # 标记来自游戏内菜单
                    elif menu_state == 'rules':
                        # 规则界面点击处理
                        # 先定义返回按钮位置，避免重复调用draw_rules_screen
                        back_button = pygame.Rect(30, 30, 80, 35)
                        
                        # 优先检测返回按钮点击
                        if back_button.collidepoint(event.pos):
                            # 返回上一步操作
                            if showing_game_menu:
                                menu_state = 'game_menu'
                                showing_rules = False
                            else:
                                menu_state = 'main'
                                showing_rules = False
                            scroll_offset = 0
                        else:
                            # 检查是否点击了滚动条
                            scrollbar_width = 12
                            scrollbar_x = WIDTH - 40
                            scrollbar_y = 120
                            content_area_height = HEIGHT - 160
                            
                            # 使用预定义的内容高度，避免重复调用绘制函数
                            if content_height > content_area_height:
                                scrollbar_rect = pygame.Rect(scrollbar_x, scrollbar_y, scrollbar_width, content_area_height)
                                if scrollbar_rect.collidepoint(event.pos):
                                    # 开始拖拽滚动条
                                    dragging_scrollbar = True
                                    scroll_ratio = (event.pos[1] - scrollbar_y) / content_area_height
                                    scroll_ratio = max(0, min(1, scroll_ratio))  # 限制在0-1范围内
                                    scroll_offset = int(scroll_ratio * max(0, content_height - content_area_height))
            elif event.type == pygame.MOUSEBUTTONUP:
                # 停止拖拽滚动条
                if event.button == 1:  # 左键释放
                    dragging_scrollbar = False
            elif event.type == pygame.MOUSEWHEEL and menu_state == 'rules':
                # 规则界面滚轮处理
                scroll_offset -= event.y * 30
                # 使用预定义的内容高度进行滚动限制
                scroll_offset = max(0, min(scroll_offset, max(0, content_height - content_area_height)))
            elif event.type == pygame.MOUSEMOTION:
                if menu_state == 'rules' and dragging_scrollbar:
                    # 拖拽滚动条
                    scrollbar_width = 12
                    scrollbar_x = WIDTH - 40
                    scrollbar_y = 120
                    content_area_height = HEIGHT - 160
                    
                    # 使用预定义的内容高度进行滚动计算
                    if content_height > content_area_height:
                        # 计算新的滚动位置
                        mouse_y = event.pos[1]
                        scroll_ratio = (mouse_y - scrollbar_y) / content_area_height
                        scroll_ratio = max(0, min(1, scroll_ratio))  # 限制在0-1范围内
                        scroll_offset = int(scroll_ratio * max(0, content_height - content_area_height))
                elif menu_state == 'exit_confirm':
                    # 更新退出确认对话框的悬停效果
                    if exit_confirm_from_main:
                        draw_main_menu_exit_confirm(screen, WIDTH, HEIGHT)
                    else:
                        draw_game_menu_exit_confirm(screen, WIDTH, HEIGHT)
                elif menu_state == 'game_menu':
                    # 更新游戏内菜单的悬停效果
                    draw_game_menu(screen, WIDTH, HEIGHT)
                elif menu_state == 'main':
                    # 更新菜单悬停效果
                    menu_buttons = draw_menu(screen, WIDTH, HEIGHT)
            elif event.type == pygame.KEYDOWN and menu_state == 'game':
                # 游戏中的键盘事件
                if event.key == pygame.K_ESCAPE:
                    menu_state = 'game_menu'
                    showing_game_menu = True
                elif event.key == pygame.K_r:
                    game_state = reset_game()
                elif event.key == pygame.K_p:
                    game_state['paused'] = not game_state['paused']
                elif event.key == pygame.K_LEFT:
                    new_offset = [game_state['offset'][0] - 1, game_state['offset'][1]]
                    if not check_collision(game_state['board'], game_state['current_shape'], new_offset):
                        game_state['offset'] = new_offset
                elif event.key == pygame.K_RIGHT:
                    new_offset = [game_state['offset'][0] + 1, game_state['offset'][1]]
                    if not check_collision(game_state['board'], game_state['current_shape'], new_offset):
                        game_state['offset'] = new_offset
                elif event.key == pygame.K_DOWN:
                    new_offset = [game_state['offset'][0], game_state['offset'][1] + 1]
                    if not check_collision(game_state['board'], game_state['current_shape'], new_offset):
                        game_state['offset'] = new_offset
                        game_state['score'] += 1
                elif event.key == pygame.K_UP:
                    rotated = rotate(game_state['current_shape'])
                    if not check_collision(game_state['board'], rotated, game_state['offset']):
                        game_state['current_shape'] = rotated
                elif event.key == pygame.K_SPACE:
                    # 硬降
                    drop_y = get_drop_position(game_state['board'], game_state['current_shape'], game_state['offset'])
                    points = (drop_y - game_state['offset'][1]) * 2
                    game_state['score'] += points
                    game_state['offset'][1] = drop_y
                    game_state['fall_time'] = 1000

        # 软降处理
        if keys_pressed[pygame.K_DOWN] and menu_state == 'game' and not game_state['paused'] and not game_state['game_over'] and not showing_game_menu:
            game_state['soft_drop_time'] += dt
            if game_state['soft_drop_time'] > 50:  # 软降速度
                new_offset = [game_state['offset'][0], game_state['offset'][1] + 1]
                if not check_collision(game_state['board'], game_state['current_shape'], new_offset):
                    game_state['offset'] = new_offset
                    game_state['score'] += 1
                game_state['soft_drop_time'] = 0

        # 更新游戏逻辑
        if menu_state == 'game' and not game_state['paused'] and not game_state['game_over'] and not showing_game_menu:
            # 处理闪烁行
            if game_state['flash_rows']:
                game_state['flash_timer'] += dt
                if game_state['flash_timer'] > 600:  # 0.6秒闪烁
                    # 生成粒子效果
                    for row in game_state['flash_rows']:
                        for col in range(COLUMNS):
                            if game_state['board'][row][col]:
                                px = col * BLOCK_SIZE + BLOCK_SIZE // 2
                                py = row * BLOCK_SIZE + BLOCK_SIZE // 2
                                color = COLORS[game_state['board'][row][col] - 1]
                                game_state['particles'].extend(spawn_particles(px, py, color))

                    # 消除行
                    game_state['board'], lines_cleared, _ = remove_full_lines(game_state['board'])
                    game_state['lines'] += lines_cleared
                    game_state['score'] += calculate_score(lines_cleared, game_state['level'])

                    # 更新等级
                    game_state['level'] = min(10, game_state['lines'] // LINES_PER_LEVEL + 1)

                    game_state['flash_rows'] = None
                    game_state['flash_timer'] = 0

                    # 生成新方块
                    game_state['current_shape'] = game_state['next_shape']
                    game_state['current_color'] = game_state['next_color']
                    game_state['next_shape'] = random.choice(SHAPES)
                    game_state['next_color'] = random.choice(COLORS)
                    game_state['offset'] = [COLUMNS // 2 - len(game_state['current_shape'][0]) // 2, 0]

                    if check_collision(game_state['board'], game_state['current_shape'], game_state['offset']):
                        game_state['game_over'] = True

            else:
                # 自动下落
                fall_speed = LEVEL_SPEEDS[min(game_state['level'] - 1, len(LEVEL_SPEEDS) - 1)]
                game_state['fall_time'] += dt

                if game_state['fall_time'] >= fall_speed:
                    game_state['fall_time'] = 0
                    new_offset = [game_state['offset'][0], game_state['offset'][1] + 1]

                    if not check_collision(game_state['board'], game_state['current_shape'], new_offset):
                        game_state['offset'] = new_offset
                    else:
                        # 锁定方块
                        for y, row in enumerate(game_state['current_shape']):
                            for x, cell in enumerate(row):
                                if cell:
                                    board_x = x + game_state['offset'][0]
                                    board_y = y + game_state['offset'][1]
                                    if 0 <= board_x < COLUMNS and 0 <= board_y < ROWS:
                                        game_state['board'][board_y][board_x] = COLORS.index(
                                            game_state['current_color']) + 1

                        # 检查完整行
                        full_rows = [i for i, row in enumerate(game_state['board']) if all(cell != 0 for cell in row)]
                        if full_rows:
                            game_state['flash_rows'] = full_rows
                            game_state['flash_timer'] = 0
                        else:
                            # 直接生成新方块
                            game_state['current_shape'] = game_state['next_shape']
                            game_state['current_color'] = game_state['next_color']
                            game_state['next_shape'] = random.choice(SHAPES)
                            game_state['next_color'] = random.choice(COLORS)
                            game_state['offset'] = [COLUMNS // 2 - len(game_state['current_shape'][0]) // 2, 0]

                            if check_collision(game_state['board'], game_state['current_shape'], game_state['offset']):
                                game_state['game_over'] = True

        # 更新粒子效果
        if menu_state == 'game' and not showing_game_menu:
            game_state['particles'] = [p for p in game_state['particles'] if p.life > 0]
            for particle in game_state['particles']:
                particle.update()

        # 绘制界面
        if menu_state == 'main':
            # 绘制主菜单
            menu_buttons = draw_menu(screen, WIDTH, HEIGHT)
            # 刷新屏幕
            pygame.display.flip()
        elif menu_state == 'rules':
            # 绘制规则界面
            back_button, content_height, content_area_height = draw_rules_screen(screen, WIDTH, HEIGHT, scroll_offset)
            # 刷新屏幕
            pygame.display.flip()
        elif menu_state == 'exit_confirm':
            # 绘制退出确认对话框
            if exit_confirm_from_main:
                # 先绘制主菜单作为背景
                menu_buttons = draw_menu(screen, WIDTH, HEIGHT)
                # 然后绘制退出确认对话框
                draw_main_menu_exit_confirm(screen, WIDTH, HEIGHT)
            else:
                # 先绘制游戏界面作为背景
                draw_board(
                    screen, game_state['board'], game_state['current_shape'], game_state['offset'],
                    game_state['current_color'], game_state['next_shape'], game_state['next_color'],
                    game_state['score'], game_state['level'], game_state['lines'],
                    game_state['flash_rows'], game_state['paused'], game_state['game_over'],
                    game_state['particles']
                )
                # 然后绘制退出确认对话框
                draw_game_menu_exit_confirm(screen, WIDTH, HEIGHT)
            # 刷新屏幕
            pygame.display.flip()
        elif menu_state == 'game_menu':
            # 绘制游戏内菜单
            # 先绘制游戏界面作为背景
            draw_board(
                screen, game_state['board'], game_state['current_shape'], game_state['offset'],
                game_state['current_color'], game_state['next_shape'], game_state['next_color'],
                game_state['score'], game_state['level'], game_state['lines'],
                game_state['flash_rows'], game_state['paused'], game_state['game_over'],
                game_state['particles']
            )
            # 然后绘制游戏内菜单
            draw_game_menu(screen, WIDTH, HEIGHT)
            # 刷新屏幕
            pygame.display.flip()
        elif menu_state == 'game':
            # 绘制游戏界面
            draw_board(
                screen, game_state['board'], game_state['current_shape'], game_state['offset'],
                game_state['current_color'], game_state['next_shape'], game_state['next_color'],
                game_state['score'], game_state['level'], game_state['lines'],
                game_state['flash_rows'], game_state['paused'], game_state['game_over'],
                game_state['particles']
            )
            # 刷新屏幕
            pygame.display.flip()

    pygame.quit()


if __name__ == '__main__':
    main()